#include "bayes_loop.h"

void BayesLoop::do_loop(int obs_id)
{
    // 根据贝叶斯公式，计算后验概率

    // 各种观察的总概率
    std::vector<double> total_obs(m_obs.size());

    for (int i = 0; i < m_obs.size(); i++)
    {
        for (int j = 0; j < m_hyp.size(); j++)
        {
            // P(i) += P(i | j) * P(j)
            total_obs[i] += m_obs[i][j] * m_hyp[j];
        }
    }

    // 后验概率列表，其中 posteriors[i][j] 表示在观察 j 发生的条件下，假设 i 发生的概率
    // 也可理解为观察 j 被假设 i 点燃的概率
    std::vector<std::vector<double>> posteriors(m_hyp.size(), std::vector<double>(m_obs.size()));

    for (int i = 0; i < m_hyp.size(); i++)
    {
        for (int j = 0; j < m_obs.size(); j++)
        {
            // P(i | j) = P(j | i) * P(i) / P(j)
            posteriors[i][j] = m_obs[j][i] * m_hyp[i] / total_obs[j];
        }
    }

    // 根据实验观察的结果计算先验概率
    // 因为 obs_id 已经发生，所以用 posteriors[i][obs_id] 代替 m_hyp[i]
    // 这也是贝叶斯循环的核心公式

    for (int i = 0; i < m_hyp.size(); i++)
    {
        m_hyp[i] = posteriors[i][obs_id];
    }

    // 循环完成
}